package me.zhengjie.modules.hanzi.service;

import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.utils.FileUtils;
import me.zhengjie.utils.MapUtil;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;

@Slf4j
@Service
@RequiredArgsConstructor
public class StrokeService {

    @Autowired
    public RestTemplate restTemplate;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    /**
     * 创建简化的笔顺数据，用于CDN访问失败时
     */
    private Map<String, Object> createSimpleStrokeData(String hanzi) {
        Map<String, Object> data = new HashMap<>();
        data.put("character", hanzi);
        data.put("strokes", new String[]{"M 0 0 L 100 100", "M 100 0 L 0 100"});
        return data;
    }

    public Map<String, Object> getStrokeGif(String character) {
        if (StrUtil.isBlank(character)) {
            return new HashMap<>();
        }
        String cacheKey = "stroke_data:" + character;
        Map<String, Object> cachedData = (Map<String, Object>) redisTemplate.opsForValue().get(cacheKey);

        if (Objects.nonNull(cachedData)) {
            try {
                // 直接返回缓存数据，不再进行额外的转换
                if (cachedData instanceof Map) {
                    return cachedData;
                } else {
                    // 如果不是Map类型，尝试转换
                    return MapUtil.objectToMap(cachedData);
                }
            } catch (Exception e) {
                log.warn("缓存数据转换失败，将重新获取数据: {}", e.getMessage());
                // 删除有问题的缓存
                redisTemplate.delete(cacheKey);
            }
        }
        
        try {
            String url = String.format("https://hanyuapp.baidu.com/dictapp/word/detail_getworddetail?wd=%s&client=pc&lesson_from=xiaodu&smp_names=wordNewData1", character);
            log.debug("请求百度汉语API: {}", url);
            
            Map forObject = restTemplate.getForObject(url, Map.class);
            log.debug("百度汉语API响应: {}", forObject);
            
            if (forObject != null && forObject.containsKey("data")) {
                Object data = forObject.get("data");
                if (Objects.nonNull(data)) {
                    Map<String, Object> resultData;
                    try {
                        resultData = MapUtil.objectToMap(data);
                    } catch (Exception e) {
                        log.error("数据转换失败，原始数据: {}, 错误: {}", data, e.getMessage());
                        throw new RuntimeException("数据转换失败: " + e.getMessage(), e);
                    }
                    
                    // 设置缓存，过期时间1天
                    redisTemplate.opsForValue().set(cacheKey, resultData, 24, TimeUnit.HOURS);
                    return resultData;
                }
            }
            
            log.error("百度汉语API返回数据结构异常，响应: {}", forObject);
            throw new RuntimeException("百度汉语API返回数据不包含汉字 " + character + " 的笔顺信息");
            
        } catch (RestClientException e) {
            log.error("获取汉字 {} 的笔顺数据时发生网络错误: {}", character, e.getMessage());
            throw new RuntimeException("网络错误: " + e.getMessage(), e);
        } catch (RuntimeException e) {
            // 重新抛出运行时异常，保持原始错误信息
            throw e;
        } catch (Exception e) {
            log.error("获取汉字 {} 的笔顺数据时发生未知错误: {}", character, e.getMessage(), e);
            throw new RuntimeException("Cannot deserialize", e);
        }
    }

    public String getStrokeImg(String character, Integer strokeNumber) {
        try {
            Map<String, Object> strokeGif = this.getStrokeGif(character);
            if (strokeGif == null || !strokeGif.containsKey("detail")) {
                String errorMsg = "获取汉字 " + character + " 的笔顺数据失败，数据结构不包含detail字段";
                log.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
            
            Object detail = strokeGif.get("detail");
            if (detail == null) {
                String errorMsg = "汉字 " + character + " 的detail字段为空";
                log.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
            
            Map<String, Object> detailMap = StringUtils.convertObjectToMap(detail);
//            detailMap = MapUtil.underlineToCamel(detailMap);
            if (!detailMap.containsKey("strokeOrder")) {
                String errorMsg = "汉字 " + character + " 的detail字段不包含strokeOrder";
                log.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
            
            Object strokeOrder = detailMap.get("strokeOrder");
            if (strokeOrder == null) {
                String errorMsg = "汉字 " + character + " 的strokeOrder字段为空";
                log.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
            
            List<StringUtils.StrokeData> strokeData = StringUtils.parseJson(strokeOrder.toString());
            if (strokeData.isEmpty()) {
                String errorMsg = "汉字 " + character + " 的笔顺数据解析为空";
                log.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
            
            // 确保所有的笔顺数据有效
            List<StringUtils.StrokeData> validStrokeData = new ArrayList<>();
            for (StringUtils.StrokeData data : strokeData) {
                if (data.isValid()) {
                    validStrokeData.add(data);
                } else {
                    log.warn("忽略无效的笔顺数据: {}", data);
                }
            }
            
            if (validStrokeData.isEmpty()) {
                String errorMsg = "汉字 " + character + " 没有有效的笔顺数据";
                log.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
            
            String svgContent = StringUtils.generateSvg(validStrokeData,strokeNumber);
            
            // 确保SVG内容有效
            if (svgContent == null || svgContent.isEmpty() || !svgContent.contains("<svg")) {
                String errorMsg = "生成的SVG内容无效: " + svgContent;
                log.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
            
            String base64Image = FileUtils.convertSvgToBase64(svgContent);
            if (base64Image == null) {
                throw new RuntimeException("转换SVG到Base64失败");
            }
            return base64Image;
            
        } catch (Exception e) {
            log.error("处理汉字 {} 时发生错误: {}", character, e.getMessage(), e);
            throw new RuntimeException("处理汉字 " + character + " 时发生错误: " + e.getMessage(), e);
        }
    }
}
